package uk.ac.aber.paws.client.idlelogger.gui;

import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.util.*;

import javax.swing.*;

import uk.ac.aber.paws.client.idlelogger.IdleLogger;
import uk.ac.aber.paws.client.idlelogger.IdleLoggerUpdater;
import uk.ac.aber.paws.client.idlelogger.events.ButtonHandler;
import uk.ac.aber.paws.client.idlelogger.events.SysTrayListener;
import uk.ac.aber.paws.client.idlelogger.events.SysTrayWindowListener;
import uk.ac.aber.paws.client.idlelogger.languages.DisableOptionHandler;
import uk.ac.aber.paws.client.idlelogger.languages.LanguageHandler;
import uk.ac.aber.paws.client.idlelogger.languages.Languages;
import uk.ac.aber.paws.client.updater.UpdateDetails;
import uk.ac.aber.paws.client.updater.UpdateManager;
import static uk.ac.aber.paws.client.constants.CommandConstants.*;

/**
 * @author Rob Johnson, Aberystwyth University
 * @email rob.johnson@aber.ac.uk
 * @date 8th August 2011
 * 
 * PAWSSysTray.java
 * 
 * Main gui for displaying the systray and its related windows for the IdleLogger
 * application
 *    
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

public class PAWSSysTray {

	private static TrayIcon trayIcon = null;
	private static JFrame mainWindow = null;
	private static JPanel mainPanel = null;
	private static SystemTray tray = null;
	private static Font defaultFont = new Font("Verdana",Font.PLAIN,10);
	private static Menu languageSel = null;
	private static Menu disablePAWS = null;
	private static Color backgroundColour = Color.white;
	private static JButton updateButton = null;
	private static final int WINDOW_HEIGHT = 400;
	private static final int WINDOW_WIDTH = 600;
	private static JPanel buttonPanel = null;
	
	public static Menu getDisablePAWS() {
		
		return disablePAWS; 
	}
	
	private static Image getIcon(String type, Dimension size) {
		
		ImageIcon image = null;
		
		try {
			if (type.equals("NORMAL")) {
				image = new ImageIcon(PAWSSysTray.class.getClassLoader().getResource("uk/ac/aber/paws/client/images/pawssmall.png"));
			}
			else if (type.equals("WARNING")) {
				image = new ImageIcon(PAWSSysTray.class.getClassLoader().getResource("uk/ac/aber/paws/client/images/pawssmallred.png"));
			}
			else if (type.equals("DISABLED")) {
				image = new ImageIcon(PAWSSysTray.class.getClassLoader().getResource("uk/ac/aber/paws/client/images/pawssmalldisabled.png"));
			}
			
			if (size != null) {
				Image img = image.getImage();   
				Image newimg = img.getScaledInstance((int)size.getWidth(),(int)size.getHeight(),java.awt.Image.SCALE_SMOOTH);
				image = new ImageIcon(newimg);  
	
			}
			return image.getImage();
		}
		catch (NullPointerException ex) {
		}
		
		return null;
	}
	
	public static void closeSysTray() {
		
		tray.remove(trayIcon);
	}
	
	public static void refreshSysTray() {
		
		closeSysTray();
		launchSysTray();
	}
	
	public static void launchSysTray() {
		
		if (SystemTray.isSupported()) {
			
			tray = SystemTray.getSystemTray();
	
			PopupMenu popup = new PopupMenu();
			
			Image image = getIcon("NORMAL",tray.getTrayIconSize());
			
			if (image != null) {
				trayIcon = new TrayIcon(image, "PAWS", popup);
			}
			
			trayIcon.addMouseListener(new SysTrayListener());
			
			MenuItem aboutItem = new MenuItem(IdleLogger.getLanguagePack().getProperty("app.menu.item1"));
			MenuItem clientManager = new MenuItem(IdleLogger.getLanguagePack().getProperty("app.menu.item2"));
			languageSel = new Menu(IdleLogger.getLanguagePack().getProperty("app.menu.item3"));
			MenuItem updateCheck = new MenuItem(IdleLogger.getLanguagePack().getProperty("app.menu.item4"));
			disablePAWS = new Menu(IdleLogger.getLanguagePack().getProperty("app.menu.item5"));
			MenuItem fixPAWS = new MenuItem(IdleLogger.getLanguagePack().getProperty("app.menu.item6"));
			MenuItem sleepNow = new MenuItem(IdleLogger.getLanguagePack().getProperty("app.menu.item7"));
			
			buildLanguageMenu(languageSel);
			
			buildDisableOptionsMenu(disablePAWS);
			
			aboutItem.addActionListener(new ButtonHandler(4));
			clientManager.addActionListener(new ButtonHandler(5));
			updateCheck.addActionListener(new ButtonHandler(6));
			fixPAWS.addActionListener(new ButtonHandler(8));
			sleepNow.addActionListener(new ButtonHandler(9));
			
			popup.setFont(defaultFont);
			popup.add(aboutItem);
			popup.add(clientManager);
			popup.add(languageSel);
			popup.add(updateCheck);
			popup.add(disablePAWS);
			popup.add(fixPAWS);
			popup.add(sleepNow);
			
			trayIcon.setToolTip(IdleLogger.getLanguagePack().getProperty("app.main.healthytooltip"));
			
			try {
				tray.add(trayIcon);
			} 
			catch (AWTException ex) {
				System.err.println("TrayIcon could not be added.");
			}
		}
	}
	
	private static void buildLanguageMenu(Menu langusageSel) {
		
		Hashtable<String,String> langs = Languages.getLangFileNames("uk/ac/aber/paws/client/idlelogger/languages/languages.cfg");
		
		Enumeration<String> e = langs.keys();
		
		while (e.hasMoreElements()) {
		
			String key = (String)e.nextElement();
			
			CheckboxMenuItem langItem = new CheckboxMenuItem(langs.get(key));
			langItem.addItemListener(new LanguageHandler(key));
			
			if (key.equals(Languages.getSelectedLanguage())) {
				langItem.setState(true);
			}
			languageSel.add(langItem);
			
		}
	}
	
	private static void buildDisableOptionsMenu(Menu disableMenu) {
		
		// build the disable options into menu item
		String disableOptions = IdleLogger.getLanguagePack().getProperty("app.menu.disableopts");
		StringTokenizer st  = new StringTokenizer(disableOptions,"|");
		int index=1;
		
		while (st.hasMoreElements()) {
			
			String key = (String)st.nextElement();
			
			CheckboxMenuItem option = new CheckboxMenuItem(key);
			option.setName("DISABLEOPTION"+index);
			option.addItemListener(new DisableOptionHandler("DISABLEOPTION"+index));
			
			disableMenu.add(option);
			
			index++;
		}
	}
	
	public static void clearOptionsMenu() {
		
		for (int i=0;i<disablePAWS.getItemCount();i++) {
			
			CheckboxMenuItem option = (CheckboxMenuItem)disablePAWS.getItem(i);
			option.setState(false);
		}
	}

	public static void resetLanguagesMenu(String key) {
	
		if (languageSel != null) {
			
			for (int i=0;i<languageSel.getItemCount();i++) {
				
				LanguageHandler handler = (LanguageHandler)languageSel.getItem(i).getListeners(ItemListener.class)[0];
				
				if (handler.getLang().equals(key)) {
					((CheckboxMenuItem)languageSel.getItem(i)).setState(true);
				}
				else {
					((CheckboxMenuItem)languageSel.getItem(i)).setState(false);
				}
			}
			
		}
	
	}
	
	private static void initMainWindow() {
		
		if (mainWindow == null) {
			mainWindow = new JFrame(IdleLogger.getLanguagePack().getProperty("app.main.title"));
			mainWindow.setSize(WINDOW_WIDTH,WINDOW_HEIGHT);
			mainWindow.setResizable(false);
			
			
			Image image = (new ImageIcon(PAWSSysTray.class.getClassLoader().getResource("uk/ac/aber/paws/client/images/pawprintnormal.png"))).getImage();
			
			Image newimg = image.getScaledInstance(35,35,java.awt.Image.SCALE_SMOOTH);
			
			
			mainWindow.setIconImage(newimg);
			mainWindow.addWindowListener(new SysTrayWindowListener());
			
			Toolkit toolkit = Toolkit.getDefaultToolkit();
			Dimension scrnsize = toolkit.getScreenSize();
			mainWindow.setLocation(((int)scrnsize.getWidth()/2)-300, ((int)scrnsize.getHeight()/2)-200);
		}
	}
	
	public static void displayWindow(String type) {
		
		if (mainWindow == null) {
			initMainWindow();
		}
		else {
			mainWindow.remove(mainPanel);
			
		}
		
		mainPanel = new JPanel();
		mainPanel.setLayout(new BorderLayout());
		
		mainPanel.setBackground(backgroundColour);
		
		JPanel headerPanel = new JPanel();
		headerPanel.setPreferredSize(new Dimension(WINDOW_WIDTH, 150));
		headerPanel.setLayout(new GridBagLayout());
		
		//headerPanel.setLayout(new BoxLayout(headerPanel,BoxLayout.Y_AXIS));
		ImageIcon titleImage = new ImageIcon(PAWSSysTray.class.getClassLoader().getResource("uk/ac/aber/paws/client/images/pawstitle.jpg"));
		Image img = titleImage.getImage();   
		Image newimg = img.getScaledInstance(275,90,java.awt.Image.SCALE_SMOOTH);   
		titleImage = new ImageIcon(newimg);  

		GridBagConstraints gbc = new GridBagConstraints();
		
		gbc.gridx=0;gbc.gridy=0;gbc.anchor=GridBagConstraints.CENTER;
		headerPanel.add(new JLabel(titleImage),gbc);
		gbc.gridx=0;gbc.gridy=1;gbc.anchor=GridBagConstraints.CENTER;
		headerPanel.add(new SwingLink(IdleLogger.getLanguagePack().getProperty("app.info.blogurl"),IdleLogger.getMainConfig().getProperty("idlelogger.blogurl")),gbc);
		
		headerPanel.setBackground(backgroundColour);
		
		JPanel infoPanel = new JPanel();
		infoPanel.setFont(new Font("Verdana",Font.PLAIN,10));
		infoPanel.setBackground(backgroundColour);
		
		buttonPanel = new JPanel();
		buttonPanel.setBackground(backgroundColour);
		
		if (type.equals("NORMAL")) {
			
			JButton infoButton = new JButton(IdleLogger.getLanguagePack().getProperty("app.buttons.infobutton"),new ImageIcon(PAWSSysTray.class.getClassLoader().getResource("uk/ac/aber/paws/client/images/info.png")));
			buttonPanel.add(infoButton);
			infoButton.addActionListener(new ButtonHandler(1));
			
			JLabel label = new JLabel(IdleLogger.getLanguagePack().getProperty("app.info.statusmessage1"),new ImageIcon(PAWSSysTray.class.getClassLoader().getResource("uk/ac/aber/paws/client/images/tick.png")),SwingConstants.LEFT);
			infoPanel.add(label);
		}	
		else if (type.equals("WARNING")) {
			
			JLabel infoLabel;

			if (IdleLogger.getServiceIsCritical()) {
				infoLabel = new JLabel(IdleLogger.getLanguagePack().getProperty("app.info.statusmessage2"),new ImageIcon(PAWSSysTray.class.getClassLoader().getResource("uk/ac/aber/paws/client/images/error.png")),SwingConstants.RIGHT);
				
				JButton fixButton = new JButton(IdleLogger.getLanguagePack().getProperty("app.buttons.rebootbutton"),new ImageIcon(PAWSSysTray.class.getClassLoader().getResource("uk/ac/aber/paws/client/images/spanner.png")));
				buttonPanel.add(fixButton);
				fixButton.addActionListener(new ButtonHandler(2));
				
			}
			else {
				infoLabel = new JLabel(IdleLogger.getLanguagePack().getProperty("app.info.statusmessage3"),new ImageIcon(PAWSSysTray.class.getClassLoader().getResource("uk/ac/aber/paws/client/images/error.png")),SwingConstants.RIGHT);
			}
			
			infoPanel.add(infoLabel);	
		}
		else if (type.equals("INFO")) {
			showInformation(infoPanel);
			
			JButton backButton = new JButton(IdleLogger.getLanguagePack().getProperty("app.buttons.backbutton"),new ImageIcon(PAWSSysTray.class.getClassLoader().getResource("uk/ac/aber/paws/client/images/back.png")));
			buttonPanel.add(backButton);
			backButton.addActionListener(new ButtonHandler(3));
			
		}
		else if (type.equals("ABOUT")) {
			
			showAboutPage(infoPanel);
		}
		else if (type.equals("UPDATES")) {
			
			Hashtable<String,Boolean> checkResults = new Hashtable<String,Boolean>();
			
			UpdateDetails update = IdleLoggerUpdater.getPawsClientDetails();
			checkResults.put(IdleLogger.getLanguagePack().getProperty("app.update.pawsclient.name"),UpdateManager.checkForUpdate(update));
			
			update = IdleLoggerUpdater.getPawsClientManagerDetails();
			checkResults.put(IdleLogger.getLanguagePack().getProperty("app.update.pawsclientmanager.name"),UpdateManager.checkForUpdate(update));
			
			boolean updateRequired = showUpdatesPage(infoPanel,checkResults);
			
			updateButton = new JButton(IdleLogger.getLanguagePack().getProperty("app.buttons.update"),new ImageIcon(PAWSSysTray.class.getClassLoader().getResource("uk/ac/aber/paws/client/images/update.png")));
			buttonPanel.add(updateButton);
			updateButton.addActionListener(new ButtonHandler(7));
			
			if (!updateRequired) {
				updateButton.setEnabled(false);
			}
		}
		
		mainPanel.add(headerPanel,BorderLayout.NORTH);
		mainPanel.add(infoPanel,BorderLayout.CENTER);
		mainPanel.add(buttonPanel,BorderLayout.SOUTH);
		
		mainWindow.add(mainPanel);
		mainWindow.validate();
		mainWindow.repaint();
		mainWindow.setVisible(true);
	}
	
	
	public static void hideWindow() {
	
		mainWindow.setVisible(false);
	}
	
	public static void handleShutdown() {
		
		int option = JOptionPane.showConfirmDialog(null, IdleLogger.getLanguagePack().getProperty("app.info.shutdownmessage"),IdleLogger.getLanguagePack().getProperty("app.main.reboot.title"), JOptionPane.YES_NO_OPTION);

		if (option == JOptionPane.YES_OPTION) {
		
			ProcessBuilder pb = new ProcessBuilder(COMMAND_REBOOT);
			
	        try {
				Process p = pb.start();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	public static void showAboutPage(JPanel infoPanel) {
		
		infoPanel.removeAll();
		infoPanel.setLayout(new BoxLayout(infoPanel,BoxLayout.Y_AXIS));
		infoPanel.setBackground(backgroundColour);
		
		infoPanel.setPreferredSize(new Dimension(WINDOW_WIDTH,200));
		
		JPanel logoPanel = new JPanel();
		logoPanel.setPreferredSize(new Dimension(WINDOW_WIDTH-100,50));
		logoPanel.add(new JLabel(new ImageIcon(PAWSSysTray.class.getClassLoader().getResource("uk/ac/aber/paws/client/images/aber.jpg"))),BorderLayout.WEST);
		logoPanel.add(new JLabel("   "));
		logoPanel.add(new JLabel(new ImageIcon(PAWSSysTray.class.getClassLoader().getResource("uk/ac/aber/paws/client/images/jisc.gif"))),BorderLayout.EAST);
		logoPanel.setBackground(backgroundColour);
		
		JPanel textPanel = new JPanel();
		textPanel.setPreferredSize(new Dimension(WINDOW_WIDTH-100,100));
		textPanel.setFont(defaultFont);
		textPanel.setBackground(backgroundColour);
		
		JTextArea ta = new JTextArea(IdleLogger.getLanguagePack().getProperty("app.info.pawsdesc"),1,50);
		
		
		ta.setLineWrap(true);
		ta.setWrapStyleWord(true);
		ta.setEditable(false);
		
		textPanel.add(ta);
		
		infoPanel.add(textPanel);
		infoPanel.add(logoPanel);
	}
	
	public static boolean showUpdatesPage(JPanel infoPanel, Hashtable<String,Boolean> info) {
		
		boolean updateRequired = false;
		
		infoPanel.removeAll();
		infoPanel.setLayout(new GridBagLayout());
		infoPanel.setBackground(backgroundColour);
		
		infoPanel.setPreferredSize(new Dimension(WINDOW_WIDTH,200));
		
		Enumeration e = info.keys();
		
		GridBagConstraints gbc = new GridBagConstraints();
		
		int count = 0;
		
		while (e.hasMoreElements()) {
			
			String key = (String)e.nextElement();
			
			if (info.get(key).booleanValue()) {
				gbc.gridx=0;gbc.gridy=count;gbc.anchor=GridBagConstraints.WEST;gbc.insets=new Insets(10,10,10,10);
				infoPanel.add(new JLabel(new ImageIcon(PAWSSysTray.class.getClassLoader().getResource("uk/ac/aber/paws/client/images/checkcross.png"))),gbc);
				gbc.gridx=1;gbc.gridy=count;gbc.anchor=GridBagConstraints.WEST;gbc.insets=new Insets(10,10,10,10);
				infoPanel.add(new JLabel(key+" - "+IdleLogger.getLanguagePack().getProperty("app.info.needsupdate")),gbc);
				
				if (!updateRequired) {
					updateRequired = true;
				}
			}
			else {
				gbc.gridx=0;gbc.gridy=count;gbc.anchor=GridBagConstraints.WEST;gbc.insets=new Insets(10,10,10,10);
				infoPanel.add(new JLabel(new ImageIcon(PAWSSysTray.class.getClassLoader().getResource("uk/ac/aber/paws/client/images/checktick.png"))),gbc);
				gbc.gridx=1;gbc.gridy=count;gbc.anchor=GridBagConstraints.WEST;gbc.insets=new Insets(10,10,10,10);
				infoPanel.add(new JLabel(key+" - "+IdleLogger.getLanguagePack().getProperty("app.info.uptodate")),gbc);
			}
			count++;
		}
		
		return updateRequired;
	}

	public static void alterUpdateButton() {
		
		if (updateButton != null) {
			updateButton.setText(IdleLogger.getLanguagePack().getProperty("app.buttons.updating"));
			updateButton.setEnabled(false);
			//updateButton.validate();
			//buttonPanel.repaint();
			//updateButton.repaint();
			//updateButton.validate();
			//updateButton.repaint();
		}
	}
	
	public static void showInformation(JPanel infoPanel) {
		
		Hashtable<String,Object> info = IdleLogger.getInfo();
		
		if (infoPanel != null) {
			
			infoPanel.removeAll();
			infoPanel.setLayout(new GridBagLayout());
			
			if (info != null) {
				Object[][] tableData = new Object[1][2];
				
				tableData = new Object[][] {{IdleLogger.getLanguagePack().getProperty("app.info.computername"),info.get("COMPUTER_NAME")},{IdleLogger.getLanguagePack().getProperty("app.info.pawsversion"),info.get("PAWS_VERSION")},{IdleLogger.getLanguagePack().getProperty("app.info.os"),info.get("OPERATING_SYSTEM")},{IdleLogger.getLanguagePack().getProperty("app.info.serialnumber"),info.get("SERIAL_NUMBER")},{IdleLogger.getLanguagePack().getProperty("app.info.domain"),info.get("DOMAIN")},{IdleLogger.getLanguagePack().getProperty("app.info.lastwake"),""},{IdleLogger.getLanguagePack().getProperty("app.info.lastsleep"),""},{IdleLogger.getLanguagePack().getProperty("app.info.usersessions"),""}};
												
				if (((Long)info.get("LAST_WAKE_TIME")).longValue() == -1) {
					tableData[5][1] = IdleLogger.getLanguagePack().getProperty("app.info.norecord");
				}
				else {
					tableData[5][1] = new Date(((Long)info.get("LAST_WAKE_TIME")).longValue()).toString();
				}
				
				if (((Long)info.get("LAST_SLEEP_TIME")).longValue() == -1) {
					tableData[6][1] = IdleLogger.getLanguagePack().getProperty("app.info.norecord");
				}
				else {
					tableData[6][1] = new Date(((Long)info.get("LAST_SLEEP_TIME")).longValue()).toString();
				}
				
				Hashtable userList = ((Hashtable)info.get("LAST_IDLE"));
				
				if (userList.size() == 0) {
					tableData[7][1] = IdleLogger.getLanguagePack().getProperty("app.info.nousers");
				}
				else {
					Enumeration e = userList.keys();
					String users = "";
					
					while (e.hasMoreElements()) {
						String key = (String)e.nextElement();
						users += key + " ("+IdleLogger.getLanguagePack().getProperty("app.info.idlefor")+" "+(((Long)userList.get(key)).longValue())+" "+IdleLogger.getLanguagePack().getProperty("app.info.millisecs")+")";
						
					}
					tableData[7][1] = users;
				}
				
				JTable table = new JTable(tableData,new Object[]{"",""});
				table.setPreferredSize(new Dimension(WINDOW_WIDTH-100,150));
				table.setShowHorizontalLines(false);
				table.setShowVerticalLines(false);
				table.setFont(defaultFont);
				
				GridBagConstraints gbc = new GridBagConstraints();
				
				gbc.gridx=0;gbc.gridy=0;gbc.anchor=GridBagConstraints.CENTER;
				
				infoPanel.add(table,gbc);
				
			}
		}
	}
	
	public static void warningMode() {
		
		trayIcon.setToolTip(IdleLogger.getLanguagePack().getProperty("app.main.poorlytooltip"));
		
		Image image = getIcon("WARNING",tray.getTrayIconSize());
		
		if (image != null) {
			trayIcon.setImage(image);
		}
	}
	
	public static void disabledMode() {
		
		trayIcon.setToolTip(IdleLogger.getLanguagePack().getProperty("app.main.disabledmode"));
		
		Image image = getIcon("DISABLED",tray.getTrayIconSize());
		
		if (image != null) {
			trayIcon.setImage(image);
		}
	}

	public static void normalMode() {
		
		trayIcon.setToolTip(IdleLogger.getLanguagePack().getProperty("app.main.healthytooltip"));
		
		Image image = getIcon("NORMAL",tray.getTrayIconSize());
		
		if (image != null) {
			trayIcon.setImage(image);
		}
	}
	
}
